﻿using Balloonerds.Algebra;

namespace RayTracer
{
    public abstract partial class Thing
    {
        public const double Tolerance = 1e-6;

        public Surface Surface { get; set; }
        public Sphere Boundary { get; set; }

        public abstract Vector GetSurfaceNormal(Vector point);
        public abstract Intersection GetIntersection(Ray ray);
        public virtual bool TestIntersection(Ray ray, double distance)
        {
            if (TestBoundaryIntersection(ray, distance))
            {
                var isect = GetIntersection(ray);
                return (
                    isect != null &&
                    isect.Distance > Tolerance &&
                    isect.Distance < distance
                    );
            }
            else
                return false;
        }

        public virtual Thing Translate(Vector position)
        {
            if (Boundary != null)
                Boundary.Translate(position);

            return this;
        }
        public virtual Thing RotateX(double radians)
        {
            if (Boundary != null)
                Boundary.RotateX(radians);

            return this;
        }
        public virtual Thing RotateY(double radians)
        {
            if (Boundary != null)
                Boundary.RotateY(radians);

            return this;
        }
        public virtual Thing RotateZ(double radians)
        {
            if (Boundary != null)
                Boundary.RotateZ(radians);

            return this;
        }

        protected virtual bool TestBoundaryIntersection(Ray ray, double distance)
        {
            if (Boundary != null)
            {
                var isect = Boundary.GetIntersection(ray);
                return (
                    isect != null &&
                    isect.Distance < distance
                    );
            }
            else
                return true;
        }
    }
}
